package com.gzyj.flink.gps.map.fatiguedriving;

import cn.hutool.core.lang.Pair;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.gzyj.flink.driver.Driverlogininfo;
import com.gzyj.flink.dto.alarm.FatigueDrivingData;
import com.gzyj.flink.dto.alarm.Kafka_VehicleNormalAlarm;
import com.gzyj.flink.dto.alarm.Kafka_VehicleRemindContent;
import com.gzyj.flink.dto.alarm.RemindContent;
import com.gzyj.flink.gps.GPSPosition;
import com.gzyj.flink.gps.config.RedisKeyPrefixConfig;
import com.gzyj.flink.gps.factory.MySQLMybatisSessionFactory;
import com.gzyj.flink.gps.factory.RedisSessionFactory;
import com.gzyj.flink.gps.mapper.mysql.MonPilaoSetMapper;
import com.gzyj.flink.gps.mapper.mysql.MonYanzhongweiguiSetMapper;
import com.gzyj.flink.gps.mapper.mysql.TsAlarmRuleMapper;
import com.gzyj.flink.gps.utils.IntUtils;
import com.gzyj.flink.gps.utils.TimeUtils;
import com.gzyj.flink.pojo.mysql.set.MonPilaoSet;
import com.gzyj.flink.pojo.mysql.set.MonYanzhongweiguiSet;
import com.gzyj.flink.pojo.mysql.set.TsAlarmRule;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.configuration.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class FatigueResolveDataProcess extends RichMapFunction<GPSPosition, FatigueDrivingResult> {

    LettuceConnectionFactory redisFactory;

    SqlSessionFactory mysql;

    private RedisTemplate<String, Object> getRedisTemplate(LettuceConnectionFactory redisSessionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisSessionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new FastJsonRedisSerializer<>(Object.class));
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    public FatigueDrivingData TryGetData_FDD(String vehId, RedisTemplate<String, Object> clusterRedisTemplate) {

        Object obj = clusterRedisTemplate.opsForValue().get(RedisKeyPrefixConfig.RedisKey_FatigueDriving + vehId);
        if (obj == null) {
            return new FatigueDrivingData();
        } else {
            return JSON.parseObject(JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect), FatigueDrivingData.class);
        }

    }

    public Driverlogininfo TryGetData_DLD(String vehId, RedisTemplate<String, Object> clusterRedisTemplate) {
        Object obj = clusterRedisTemplate.opsForValue().get(RedisKeyPrefixConfig.RedisKey_DriverSignOn + vehId);
        if (obj == null) {
            return new Driverlogininfo();
        } else {
            return JSON.parseObject(JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect), Driverlogininfo.class);
        }

    }

    @Override
    public void open(Configuration parameters) throws Exception {
        redisFactory = RedisSessionFactory.getRedisFactory();
        mysql = MySQLMybatisSessionFactory.getSqlSessionFactory();
    }


    @Override
    public void close() throws Exception {
        super.close();
    }

    public Pair<Boolean, MonPilaoSet> GetRuleSetting(GPSPosition gpsPosition, MonPilaoSetMapper monPilaoSetMapper, TsAlarmRuleMapper tsAlarmRuleMapper) {
        MonPilaoSet setting = monPilaoSetMapper.selectByVehID(gpsPosition.getVehId());
        if (setting != null) {
            return new Pair<>(true, setting);
        } else {
            TsAlarmRule rule = tsAlarmRuleMapper.selectByRuleTypePilao(gpsPosition.getShiyongxingzhi());
            if (rule == null || rule.getRuleFlag() == 0) {
                return new Pair<>(false, setting);
            } else {
                setting = monPilaoSetMapper.selectByVehID(gpsPosition.getVehId());
                if (setting != null) {
                    return new Pair<>(true, setting);
                } else {
                    return new Pair<>(false, setting);
                }
            }
        }
    }

    private Kafka_VehicleNormalAlarm SendAlarmToKafka(FatigueDrivingData data, GPSPosition gps, Driverlogininfo driverLoginData, boolean isAlarm) {
        Kafka_VehicleNormalAlarm alarm = new Kafka_VehicleNormalAlarm();
        alarm.setVehicleId(gps.getVehId());
        alarm.setDeptId(gps.getDeptId());
        alarm.setNote("疲劳驾驶");
        alarm.setVelocity(gps.getSpeedExt());
        alarm.setAlarmBeginTime(TimeUtils.date2Str(data.getAlarmBeginTime()));
        alarm.setAlarmEndTime(TimeUtils.date2Str(data.getAlarmEndTime()));
        alarm.setAlarmTimeSpan(TimeUtils.getMinusSecond(data.getAlarmEndTime(), data.getAlarmBeginTime()));
        alarm.setMaxSpeed(data.getAlarmMaxSpeed());
        alarm.setDistance(data.getAlarmDistance() * 1000);
        alarm.setLimited(0);
        alarm.setLongitude(gps.getLngExt());
        alarm.setLatitude(gps.getLatExt());
        alarm.setElevation(0d);
        alarm.setAngle(gps.getDIRECTION());
        alarm.setLocal(IntUtils.LocalExt(gps.getSTATUSBIT()) == 1);
        alarm.setAnalyzeModel(1);
        alarm.setCreateTime(TimeUtils.getNow());
        alarm.setUpdateTime(TimeUtils.getNow());
        alarm.setTime(gps.getTIME());
        alarm.setIsAlarm(isAlarm);
        alarm.setAlarmGuid(data.getSingleGuid());
        alarm.setCalcTime(TimeUtils.date2Str(data.getConditionBeginTime()));
        alarm.setDriver(driverLoginData.getDriverName());
        alarm.setDriverNo(driverLoginData.getDriverNo());
        alarm.setQualificationCode(driverLoginData.getDriverNo());
        alarm.setAlarmLevel(data.getAlarmLevel());
        alarm.setAlarmSetting(data.getAlarmSetting());
        alarm.setRestTime(TimeUtils.getMinusSecond(data.getRestEndTime(), data.getRestBeginTime()));

        return alarm;
    }

    private RemindContent GenerateVehicleRemind(FatigueDrivingData data, MonPilaoSet setting, GPSPosition gps, String msgType) {
        try {
            if (msgType.equalsIgnoreCase("预警短信")) {
                RemindContent content = new RemindContent() {
                    {
                        VehicleId = gps.getVehId();
                        Ipaddress = gps.getTerminalPhoneNo();
                        VehicleNo = gps.getCheliangpaizhao();
                        PlateColor = gps.getChepaiyanse();
                        RemindNote = setting.getTxnr();
                        RemindType = 0x01;
                        RemindTime = new Date();
                        MessageType = "疲劳驾驶报警";
                        AlarmNote = "疲劳驾驶报警";
                        AlarmGuid = data.SingleGuid;
                        GpsTime = data.GpsTime;
                        LastSpeed = gps.getSpeedExt();
                    }

                };
                if (!data.IsCalcInNight) {
                    //白天
                    content.RemindNote = content.RemindNote.replace("{时间}", (int) ((setting.getPlzcjssj() * 60 * 60 - data.CalcConditionTimeSpan()) / 60) + "分钟");
                } else {
                    //夜间
                    content.RemindNote = content.RemindNote.replace("{时间}", (int) ((setting.getYjplzcjssj() * 60 * 60 - data.CalcConditionTimeSpan()) / 60) + "分钟");
                }
                return content;
            } else if (msgType.equalsIgnoreCase("报警短信")) {
                RemindContent content = new RemindContent() {
                    {
                        VehicleId = gps.getVehId();
                        Ipaddress = gps.getTerminalPhoneNo();
                        VehicleNo = gps.getCheliangpaizhao();
                        PlateColor = gps.getChepaiyanse();
                        RemindNote = setting.getBjnr();
                        RemindType = 0x02;
                        RemindTime = new Date();
                        MessageType = "疲劳驾驶报警";
                        AlarmNote = "疲劳驾驶报警";
                        AlarmGuid = data.SingleGuid;
                        GpsTime = data.GpsTime;
                        LastSpeed = gps.getSpeedExt();
                    }

                };
                return content;
            } else {
                return null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private Kafka_VehicleRemindContent SendRemindToKafka(RemindContent remindContent) {

        Kafka_VehicleRemindContent kafkaVehicleRemindContent = new Kafka_VehicleRemindContent();
        kafkaVehicleRemindContent.setVehId(remindContent.getVehicleId());
        kafkaVehicleRemindContent.setVehNo(remindContent.getVehicleNo());
        kafkaVehicleRemindContent.setPlateColor(remindContent.getPlateColor());
        kafkaVehicleRemindContent.setRemindNote(remindContent.getRemindNote());
        kafkaVehicleRemindContent.setRemindTime(new Date());
        kafkaVehicleRemindContent.setRemindType(remindContent.getRemindType());
        kafkaVehicleRemindContent.setMessageType(remindContent.getMessageType());
        kafkaVehicleRemindContent.setAlarmNote(remindContent.getAlarmNote());
        kafkaVehicleRemindContent.setAlarmGuid(remindContent.getAlarmGuid());
        kafkaVehicleRemindContent.setGpsTime(remindContent.getGpsTime());
        kafkaVehicleRemindContent.setLastSpeed(remindContent.getLastSpeed());

        return kafkaVehicleRemindContent;


    }

    private MonYanzhongweiguiSet getVehicleForSeverityAlarmParamsDic(String vehiId, MonYanzhongweiguiSetMapper monYanzhongweiguiSetMapper) {
        return monYanzhongweiguiSetMapper.selectByVehId(vehiId);
    }

    public Pair<Boolean, MonYanzhongweiguiSet> GetSeverityRuleSetting(GPSPosition vehicle, MonYanzhongweiguiSetMapper monYanzhongweiguiSetMapper, TsAlarmRuleMapper tsAlarmRuleMapper) {
        MonYanzhongweiguiSet setting = getVehicleForSeverityAlarmParamsDic(vehicle.getVehId(), monYanzhongweiguiSetMapper);
        if (setting != null) {
            return new Pair<>(true, setting);
        } else {

            List<TsAlarmRule> list = tsAlarmRuleMapper.selectByRuleTypeYanzhong(vehicle.getShiyongxingzhi());

            TsAlarmRule rule = list.size() > 0 ? list.get(0) : null;

            if (rule == null || rule.getRuleFlag() == 0) {
                return new Pair<>(false, setting);
            } else {
                setting = getVehicleForSeverityAlarmParamsDic(rule.getRuleNo(), monYanzhongweiguiSetMapper);
                if (setting != null) {
                    return new Pair<>(true, setting);
                } else {
                    return new Pair<>(false, setting);
                }
            }
        }
    }

    private Kafka_VehicleNormalAlarm DisposeAlarmLevel(FatigueDrivingData fatigueDrivingData, GPSPosition gps, MonYanzhongweiguiSetMapper monYanzhongweiguiSetMapper, TsAlarmRuleMapper tsAlarmRuleMapper) {
        Pair<Boolean, MonYanzhongweiguiSet> p = GetSeverityRuleSetting(gps, monYanzhongweiguiSetMapper, tsAlarmRuleMapper);
        MonYanzhongweiguiSet severityAlarmSetting = p.getValue();
        if (p.getKey()) {
            if (severityAlarmSetting.getQy5jgz() != null && severityAlarmSetting.getQy5jgz() == 1) {
                fatigueDrivingData.AlarmSetting = 2;
                // 新疆5级规则
                double interval = TimeUtils.getMinusSecond(new Date(), fatigueDrivingData.AlarmBeginTime) / 60;
                int fifthDuration = 120;

                int fourthDuration = 60;

                int thirdDuration = 30;

                int secondDuration = 20;
                if (interval >= fifthDuration) {
                    //五级报警
                    if (fatigueDrivingData.AlarmLevel < 5) {
                        fatigueDrivingData.AlarmLevel = 5;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                } else if (interval >= fourthDuration) {
                    //四级报警
                    if (fatigueDrivingData.AlarmLevel < 4) {
                        fatigueDrivingData.AlarmLevel = 4;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                } else if (interval >= thirdDuration) {
                    //三级报警
                    if (fatigueDrivingData.AlarmLevel < 3) {
                        fatigueDrivingData.AlarmLevel = 3;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                } else if (interval >= secondDuration) {
                    //二级报警
                    if (fatigueDrivingData.AlarmLevel < 2) {
                        fatigueDrivingData.AlarmLevel = 2;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                }

            } else {
                fatigueDrivingData.AlarmSetting = 1;
                // 通用规则
                double interval = TimeUtils.getMinusSecond(fatigueDrivingData.AlarmEndTime, fatigueDrivingData.AlarmBeginTime) / 60;

                int thirdDuration = severityAlarmSetting.getPlcxsj();

                int secondDuration = severityAlarmSetting.getPlcxsj2();
                if (interval >= thirdDuration) {
                    //三级报警
                    if (fatigueDrivingData.AlarmLevel < 3) {
                        fatigueDrivingData.AlarmLevel = 3;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                } else if (interval >= secondDuration) {
                    //二级报警
                    if (fatigueDrivingData.AlarmLevel < 2) {
                        fatigueDrivingData.AlarmLevel = 2;
                        return SendAlarmLevelToKafka(fatigueDrivingData, gps, false);
                    }
                }

            }
        }
        return null;
    }

    private Kafka_VehicleNormalAlarm SendAlarmLevelToKafka(FatigueDrivingData data, GPSPosition gps, boolean isWarning) {

        Kafka_VehicleNormalAlarm alarm = new Kafka_VehicleNormalAlarm();
        alarm.setVehicleId(gps.getVehId());
        alarm.setDeptId(gps.getDeptId());
        alarm.setNote("疲劳驾驶");
        alarm.setVelocity(gps.getSpeedExt());
        alarm.setAlarmBeginTime(TimeUtils.date2Str(data.AlarmBeginTime));
        alarm.setAlarmEndTime(TimeUtils.date2Str(data.AlarmEndTime));
        alarm.setAlarmTimeSpan((data.AlarmEndTime.getTime() - data.AlarmBeginTime.getTime()) / 1000);
        alarm.setMaxSpeed(data.AlarmMaxSpeed);
        alarm.setDistance(data.AlarmDistance * 1000);
        alarm.setLimited(0);
        alarm.setLongitude(gps.getLngExt());
        alarm.setLatitude(gps.getLatExt());
        alarm.setElevation(0d);
        alarm.setAngle(gps.getDIRECTION());
        alarm.setLocal(IntUtils.LocalExt(gps.getSTATUSBIT()) == 1);
        alarm.setAnalyzeModel(1);
        alarm.setCreateTime(TimeUtils.getNow());
        alarm.setUpdateTime(TimeUtils.getNow());
        alarm.setTime(gps.getTIME());
        alarm.setIsAlarm(true);
        alarm.setAlarmGuid(data.getSingleGuid());
        alarm.setCalcTime(TimeUtils.date2Str(data.ConditionBeginTime));
        alarm.setDriver("");
        alarm.setDriverNo("");
        alarm.setQualificationCode("");
        alarm.setAlarmLevel(data.getAlarmLevel());
        if (isWarning) {
            alarm.setAlarmLevel(99);
        }
        return alarm;
    }

    private FatigueDrivingResult DisposeMessage(FatigueDrivingData fatigueDrivingData, MonPilaoSet mySetting, GPSPosition gps, String msgType) {
        FatigueDrivingResult fatigueDrivingResult = new FatigueDrivingResult();
        if (msgType.equalsIgnoreCase("预警短信")) {
            if (mySetting.getTxcs() > 0 && StringUtils.isNotEmpty(mySetting.getTxnr())) {
                long ts = (new Date().getTime() - fatigueDrivingData.WarningContentSendTime.getTime()) / 1000;
                if (ts >= mySetting.getTxjg() && fatigueDrivingData.WarningContentCount < mySetting.getTxcs()) {
                    fatigueDrivingData.WarningContentCount++;
                    fatigueDrivingData.WarningContentSendTime = new Date();
                    RemindContent remindContent = GenerateVehicleRemind(fatigueDrivingData, mySetting, gps, msgType);
                    fatigueDrivingResult.setKafkaVehicleRemindContent(SendRemindToKafka(remindContent));
                    //专门给预警这个报警类型设置一个单独的GUID
                    String singleGuid = UUID.randomUUID().toString().replaceAll("-", "");

                    fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmLevelToKafka(fatigueDrivingData, gps, true));
                }
            }
        } else if (msgType.equalsIgnoreCase("报警短信")) {
            if (mySetting.getBjcs() > 0 && StringUtils.isNotEmpty(mySetting.getBjnr())) {
                long ts = TimeUtils.getMinusSecond(new Date(), fatigueDrivingData.AlarmContentSendTime);
                if (ts >= mySetting.getBjjg() && fatigueDrivingData.AlarmContentCount < mySetting.getBjcs()) {
                    fatigueDrivingData.AlarmContentCount++;
                    fatigueDrivingData.AlarmContentSendTime = new Date();
                    RemindContent remindContent = GenerateVehicleRemind(fatigueDrivingData, mySetting, gps, msgType);
                    fatigueDrivingResult.setKafkaVehicleRemindContent(SendRemindToKafka(remindContent));
                }
            }
        }

        return fatigueDrivingResult;
    }

    @Override
    public FatigueDrivingResult map(GPSPosition gpsPosition) throws Exception {
        boolean igoreCheckTime = false;

        RedisTemplate<String, Object> clusterRedisTemplate = getRedisTemplate(redisFactory);
        SqlSession sqlSession = mysql.openSession(true);
        FatigueDrivingResult fatigueDrivingResult = new FatigueDrivingResult();

        try {
            TsAlarmRuleMapper tsAlarmRuleMapper = sqlSession.getMapper(TsAlarmRuleMapper.class);
            MonPilaoSetMapper monPilaoSetMapper = sqlSession.getMapper(MonPilaoSetMapper.class);
            MonYanzhongweiguiSetMapper monYanzhongweiguiSetMapper = sqlSession.getMapper(MonYanzhongweiguiSetMapper.class);


            FatigueDrivingData fatigueDrivingData = TryGetData_FDD(gpsPosition.getVehId(), clusterRedisTemplate);
            if (fatigueDrivingData == null) return null;
            Driverlogininfo driverLoginData;
            driverLoginData = TryGetData_DLD(gpsPosition.getVehId(), clusterRedisTemplate);
            if (driverLoginData == null) return null;
            String cancelKey = fatigueDrivingData.SingleGuid;

            Object obj = clusterRedisTemplate.opsForValue().get(RedisKeyPrefixConfig.RedisKey_MonitorAlarmCancelDic + cancelKey);
            if (obj != null) {
                String vehicleid = (String) obj;
                if (fatigueDrivingData.IsAlarm) {

                    fatigueDrivingData.StopAlarm(gpsPosition, "");

                }

                fatigueDrivingData.GenerateSingleGuid();
                fatigueDrivingData.ResetData();

                clusterRedisTemplate.delete(RedisKeyPrefixConfig.RedisKey_MonitorAlarmCancelDic + cancelKey);
            }

            Long specialConditionTimeSpan = 0L;
            Pair<Boolean, Integer> p = TimeUtils.CheckData(fatigueDrivingData.getGpsTime(), gpsPosition.getTIME());
            if (!p.getKey() && !igoreCheckTime) {
                return null;
            } else {
                //走到这里因为是IsCalc所以初始必定有值
                //计算当前点与上一个计算点得时间差，可以理解为正常回传间隔或者是掉线时间
                specialConditionTimeSpan = TimeUtils.getMinusSecond(gpsPosition.getTIME(), fatigueDrivingData.GpsTime);
                fatigueDrivingData.LocalTime = new Date();
                fatigueDrivingData.GpsTime = gpsPosition.getGPSTimeExt();
            }

            //获取运算参数
            Pair<Boolean, MonPilaoSet> p1 = GetRuleSetting(gpsPosition, monPilaoSetMapper, tsAlarmRuleMapper);
            MonPilaoSet mySetting = p1.getValue();

            if (p1.getKey()) {

                if (mySetting.getEnable() == 1) {
                    //如果车辆配置了规则
                    boolean continueFlag = true;
                    //处理一些断线或者换驾驶员得特殊情况
                    if (fatigueDrivingData.IsCalc) {
                        //计算已经休息得时间
                        long restTimeSpan = fatigueDrivingData.CalcRestTimeSpan();
                        //判断正常回传间隔或者是掉线时间是否直接满足白天或者夜间得最小休息时间，满足则直接可以结束报警
                        boolean isConditionRest = !fatigueDrivingData.IsRestInNight &&
                                specialConditionTimeSpan > mySetting.getPlzxxxsj() * 60;
                        boolean isConditionNightRest = fatigueDrivingData.IsRestInNight &&
                                specialConditionTimeSpan > mySetting.getYjplzxxxsj() * 60;
                        //判断正常回传间隔或者是掉线时间加上已经休息得时间是否直接满足白天或者夜间得最小休息时间，满足则直接可以结束报警
                        //把回传间隔小于5分钟得理解为正常回传.否则就要算在 断线时间+已经休息时间规则里
                        boolean isSpecialRest = specialConditionTimeSpan < 5 * 60 ? false : !fatigueDrivingData.IsRestInNight &&
                                specialConditionTimeSpan + restTimeSpan >= mySetting.getPlzxxxsj() * 60;
                        boolean isSpecialNightRest = specialConditionTimeSpan < 5 * 60 ? false : fatigueDrivingData.IsRestInNight &&
                                specialConditionTimeSpan + restTimeSpan >= mySetting.getYjplzxxxsj() * 60;
                        //判断驾驶员是否变更
                        boolean isDriverChangeRest = false;
                        if (mySetting.getIckdq() == 1) {
                            isDriverChangeRest = false;
                        } else if (StringUtils.isNotEmpty(fatigueDrivingData.DriverNo) && StringUtils.isNotEmpty(driverLoginData.getDriverName())) {
                            isDriverChangeRest = !fatigueDrivingData.DriverNo.equalsIgnoreCase(driverLoginData.getDriverNo());
                        }

                        if (isConditionRest || isConditionNightRest) {
                            //断线时间直接大于休息时间
                            if (fatigueDrivingData.IsAlarm) {
                                fatigueDrivingData.StopAlarm(gpsPosition, fatigueDrivingData.IsRest ? TimeUtils.date2Str(fatigueDrivingData.RestBeginTime) : TimeUtils.date2Str(fatigueDrivingData.ConditionEndTime));
                                //从报警切换到没报警，发送停止报警
                                fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                            }

                            fatigueDrivingData.GenerateSingleGuid();
                            //额外处理
                            fatigueDrivingData.ResetData();
                            continueFlag = false;
                        } else if (isSpecialRest || isSpecialNightRest) {
                            //断线时间+已经休息时间大于休息时间
                            if (fatigueDrivingData.IsAlarm) {
                                fatigueDrivingData.StopAlarm(gpsPosition, TimeUtils.date2Str(fatigueDrivingData.getRestBeginTime()));
                                //从报警切换到没报警，发送停止报警
                                fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                            }

                            fatigueDrivingData.GenerateSingleGuid();
                            //额外处理
                            fatigueDrivingData.ResetData();
                            continueFlag = false;
                        } else if (isDriverChangeRest) {
                            //更换了驾驶员
                            if (fatigueDrivingData.IsAlarm) {
                                fatigueDrivingData.StopAlarm(gpsPosition, "");
                                //从报警切换到没报警，发送停止报警
                                fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                            }

                            fatigueDrivingData.GenerateSingleGuid();
                            //额外处理
                            fatigueDrivingData.ResetData();
                            continueFlag = false;
                        }
                    }

                    if (continueFlag) {
                        //正常处理流程
                        if (gpsPosition.getSpeedExt() > 15) {
                            //如果没有计算则开始计算
                            if (!fatigueDrivingData.IsCalc) {
                                fatigueDrivingData.ResetData();
                                fatigueDrivingData.StartCalc(gpsPosition, mySetting.getYjkssj(), mySetting.getYjjssj());
                            }
                            fatigueDrivingData.WriteCalc(gpsPosition);

                            MutableTriple<Boolean, Double, Double> m = TimeUtils.CalcFatigueTime(fatigueDrivingData.ConditionBeginTime, fatigueDrivingData.ConditionEndTime, mySetting.getYjkssj(), mySetting.getYjjssj());
                            double baitian = m.middle;
                            double yejian = m.right;

                            boolean isAlarm = (baitian + yejian > mySetting.getPlzcjssj()*60*60) || (yejian > mySetting.getYjplzcjssj() * 60 * 60);

                            if (isAlarm) {
                                if (!fatigueDrivingData.IsAlarm) {
                                    fatigueDrivingData.StartAlarm(gpsPosition);
                                    //从没报警切换到报警，发送开始报警
                                    fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, true));

                                }
                                fatigueDrivingData.WriteAlarm(gpsPosition);

                                FatigueDrivingResult tmp = DisposeMessage(fatigueDrivingData, mySetting, gpsPosition, "报警短信");

                                if (tmp != null) {
                                    if (tmp.getKafkaVehicleNormalAlarm() != null)
                                        fatigueDrivingResult.setKafkaVehicleNormalAlarm(tmp.getKafkaVehicleNormalAlarm());
                                    if (tmp.getKafkaVehicleRemindContent() != null)
                                        fatigueDrivingResult.setKafkaVehicleRemindContent(tmp.getKafkaVehicleRemindContent());
                                }


                                Kafka_VehicleNormalAlarm normalAlarm = DisposeAlarmLevel(fatigueDrivingData, gpsPosition, monYanzhongweiguiSetMapper, tsAlarmRuleMapper);
                                if (normalAlarm != null) {
                                    fatigueDrivingResult.setKafkaVehicleNormalAlarm(normalAlarm);
                                }


                            } else {
                                //生成预警短信,如果生成过，则添加无效
                                boolean isWaring = ((baitian + yejian) > mySetting.getPlzcjssj() * 60 * 60 - mySetting.getTqsj() * 60)
                                        || (yejian > mySetting.getYjplzcjssj() * 60 * 60 - mySetting.getTqsj() * 60);

                                if (isWaring) {
                                    DisposeMessage(fatigueDrivingData, mySetting, gpsPosition, "预警短信");
                                }
                            }

                            fatigueDrivingData.ResetRest();

                        } else {

                            if (!fatigueDrivingData.IsRest) {
                                fatigueDrivingData.StartRest(gpsPosition, mySetting.getYjkssj(), mySetting.getYjjssj());
                            }
                            fatigueDrivingData.WriteRest(gpsPosition);
                            boolean isRest = !fatigueDrivingData.IsRestInNight &&
                                    fatigueDrivingData.CalcRestTimeSpan() >=mySetting.getPlzxxxsj() * 60;
                            boolean isNightRest = fatigueDrivingData.IsRestInNight &&
                                    fatigueDrivingData.CalcRestTimeSpan() >= mySetting.getYjplzxxxsj() * 60;
                            if (isRest || isNightRest) {
                                if (fatigueDrivingData.IsAlarm) {
                                    fatigueDrivingData.StopAlarm(gpsPosition, TimeUtils.date2Str(fatigueDrivingData.RestBeginTime));
                                    //从报警切换到没报警，发送停止报警
                                    fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                                }

                                fatigueDrivingData.GenerateSingleGuid();
                                fatigueDrivingData.ResetData();
                            }

                        }


                    }


                } else {
                    //关闭了规则
                    if (fatigueDrivingData.IsAlarm) {
                        //从报警状态切换未报警状态
                        fatigueDrivingData.StopAlarm(gpsPosition, "");
                        //从报警切换到没报警，发送停止报警
                        fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                    }
                    fatigueDrivingData.GenerateSingleGuid();
                    fatigueDrivingData.ResetData();
                }
            } else {
                //找不到规则
                if (fatigueDrivingData.IsAlarm) {
                    //从报警状态切换未报警状态
                    fatigueDrivingData.StopAlarm(gpsPosition, "");
                    //从报警切换到没报警，发送停止报警
                    fatigueDrivingResult.setKafkaVehicleNormalAlarm(SendAlarmToKafka(fatigueDrivingData, gpsPosition, driverLoginData, false));

                }
                fatigueDrivingData.GenerateSingleGuid();
                fatigueDrivingData.ResetData();
            }

            clusterRedisTemplate.opsForValue().set(RedisKeyPrefixConfig.RedisKey_FatigueDriving + gpsPosition.getVehId(), fatigueDrivingData, 8, TimeUnit.HOURS);


        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }

        return fatigueDrivingResult;
    }
}
